package com.gitee.fastmybatis.core;

import com.gitee.fastmybatis.core.ext.ExtContext;
import com.gitee.fastmybatis.core.ext.info.EntityInfo;
import com.gitee.fastmybatis.core.mapper.CrudMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @author thc
 */
public class FastmybatisContext {

    private static final Log LOG = LogFactory.getLog(FastmybatisContext.class);

    private static final Map<String, EntityInfo> ENTITY_INFO_MAP = new HashMap<>(16);

    private static ApplicationContext applicationContext;

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static void setApplicationContext(ApplicationContext applicationContext) {
        FastmybatisContext.applicationContext = applicationContext;
    }

    public static CrudMapper<Object, ?> getMapper(Object obj) {
        return getMapper(obj.getClass());
    }

    public static <E, I> CrudMapper<E, I> getMapper(Class<?> clazz) {
        Class<?> mapperClass = ExtContext.getMapperClass(clazz);
        return (CrudMapper<E, I>) applicationContext.getBean(mapperClass);
    }

    public static EntityInfo getEntityInfo(Class<?> entityClass) {
        return ENTITY_INFO_MAP.get(entityClass.getName());
    }

    public static void setEntityInfo(Class<?> entityClass, EntityInfo entityInfo) {
        ENTITY_INFO_MAP.put(entityClass.getName(), entityInfo);
    }

    /**
     * 获取实体类对应的数据库主键名称
     * @param entityClass 实体类class
     * @return 返回数据库主键名称
     */
    public static String getPkColumnName(Class<?> entityClass) {
        EntityInfo entityInfo = getEntityInfo(entityClass);
        if (entityInfo == null) {
            return null;
        }
        return entityInfo.getPkColumnName();
    }

    /**
     * 获取实体类主键对应的JAVA字段名称
     * @param entityClass 实体类class
     * @return 返回主键java字段名称
     */
    public static String getPkJavaName(Class<?> entityClass) {
        EntityInfo entityInfo = getEntityInfo(entityClass);
        if (entityInfo == null) {
            return null;
        }
        return entityInfo.getPkJavaName();
    }

    /**
     * 获取主键值
     *
     * @param entity 实体类对象
     * @return 返回主键值
     */
    public static Object getPkValue(Object entity) {
        if (entity == null) {
            return null;
        }
        Class<?> entityClass = entity.getClass();
        String pkJavaName = getPkJavaName(entityClass);
        Field field = ReflectionUtils.findField(entityClass, pkJavaName);
        ReflectionUtils.makeAccessible(field);
        try {
            return field.get(entity);
        } catch (IllegalAccessException e) {
            LOG.error("反射出错", e);
            return null;
        }
    }

}
